﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Linq;
using System.Runtime.Serialization;
using System.Text;
using System.Web.UI.WebControls;
using NetDon.OA.Data;
using NetDon.OA.Data.CollectionClasses;
using NetDon.OA.Data.DaoClasses;
using NetDon.OA.Data.EntityClasses;
using NetDon.OA.Data.HelperClasses;
using NetDon.OA.Data.Linq;
using NetDon.OA.Data.RelationClasses;
using NetDon.OA.Interface;
using NetDon.OA.Interface.Common;
using NetDon.OA.Interface.eLogistics;
using NetDon.Utilities;
using SD.LLBLGen.Pro.ORMSupportClasses;

namespace NetDon.OA.Business
{
    public class IssuingOrderOnWayTrackService : IIssuingOrderOnWayTrackService
    {
        #region Public
        public int GetOrderCount(IssuingOrderOnWayTrackSearchCriteria criteria)
        {
            var collection = new IssuingOrderOnWayTrackCollection();

            return collection.GetDbCount(GetIssuingOrderOnWayTrackSearchPredicate(criteria), GetIssuingOrderOnWayTrackSearchRelations());
        }

        public DataTable SearchIssuingOrderOnWayTrackByCondition(IssuingOrderOnWayTrackSearchCriteria criteria, string sortExpression, SortDirection sortDirection, int pageSize, int pageIndex)
        {
            var fields = new EntityFields(22);
            var index = 0;
            fields[index++] = IssuingOrderOnWayTrackFields.Id;
            fields[index++] = IssuingOrderOnWayTrackFields.IssuingOrderId;
            fields[index++] = IssuingOrderOnWayTrackFields.GoodsTravelDays;
            fields[index++] = IssuingOrderOnWayTrackFields.GoodsCurrentPlace;
            fields[index++] = IssuingOrderOnWayTrackFields.PlannedGoodsDeliveredDate;
            fields[index++] = IssuingOrderOnWayTrackFields.ActualDeliveredDate;
            fields[index++] = IssuingOrderOnWayTrackFields.GoodsDelayedDays;
            fields[index++] = IssuingOrderOnWayTrackFields.IsGoodsDelayed;
            fields[index++] = IssuingOrderOnWayTrackFields.IsGoodsExceptional;
            fields[index++] = IssuingOrderOnWayTrackFields.GoodsTravelDaysUnit;
            fields[index++] = IssuingOrderOnWayTrackFields.LastGoodsCurrentPlaceUpdatedDate;

            fields[index++] = IssuingOrderOnWayTrackFields.LastUpdatedBy;
            fields[index++] = IssuingOrderOnWayTrackFields.LastUpdatedDate;


            fields[index++] = IssuingOrderFields.BusinessType;
            fields[index++] = IssuingOrderFields.TransportationPlanCode;
            fields[index++] = IssuingOrderFields.OrderCode;
            fields[index++] = IssuingOrderFields.GoodsShippedTypeId;
            fields[index++] = IssuingOrderFields.ReceivingOrderDate;
            fields[index++] = IssuingOrderFields.OrderStatus;
            //fields[index++] = IssuingOrderFields.CheckoutType;
            //fields[index++] = IssuingOrderFields.OrderVehicleNumber;
            //fields[index++] = IssuingOrderFields.OrderQuantity;
            //fields[index++] = IssuingOrderFields.OrderVolumn;
            //fields[index++] = IssuingOrderFields.DeliveryCity;
            //fields[index++] = IssuingOrderFields.DeliveryAddress;
            //fields[index++] = IssuingOrderFields.VehicleNumber;
            //fields[index++] = IssuingOrderFields.DriverTelephone;



            fields[index++] = CustomerInfoFields.CustomerName;
            fields[index++] = IssuingOrderFields.RouteTypeId;
            fields[index++] = UserFields.UserName;



            EntityField sortField = null;
            switch (sortExpression)
            {
                case "BusinessType":
                    sortField = IssuingOrderFields.BusinessType;
                    break;
                case "TransportationPlanCode":
                    sortField = IssuingOrderFields.TransportationPlanCode;
                    break;
                case "OrderCode":
                    sortField = IssuingOrderFields.OrderCode;
                    break;
                case "GoodsShippedTypeId":
                    sortField = IssuingOrderFields.GoodsShippedTypeId;
                    break;
                case "ReceivingOrderDate":
                    sortField = IssuingOrderFields.ReceivingOrderDate;
                    break;
                case "OrderStatus":
                    sortField = IssuingOrderFields.OrderStatus;
                    break;
                case "CustomerName":
                    sortField = CustomerInfoFields.CustomerName;
                    break;
                case "RouteTypeId":
                    sortField = IssuingOrderFields.RouteTypeId;
                    break;


                case "IssuingOrderId":
                    sortField = IssuingOrderOnWayTrackFields.IssuingOrderId;
                    break;
                case "GoodsTravelDays":
                    sortField = IssuingOrderOnWayTrackFields.GoodsTravelDays;
                    break;
                case "GoodsCurrentPlace":
                    sortField = IssuingOrderOnWayTrackFields.GoodsCurrentPlace;
                    break;
                case "PlannedGoodsDeliveredDate":
                    sortField = IssuingOrderOnWayTrackFields.PlannedGoodsDeliveredDate;
                    break;
                case "ActualDeliveredDate":
                    sortField = IssuingOrderOnWayTrackFields.ActualDeliveredDate;
                    break;
                case "GoodsDelayedDays":
                    sortField = IssuingOrderOnWayTrackFields.GoodsDelayedDays;
                    break;
                case "IsGoodsDelayed":
                    sortField = IssuingOrderOnWayTrackFields.IsGoodsDelayed;
                    break;
                case "IsGoodsExceptional":
                    sortField = IssuingOrderOnWayTrackFields.IsGoodsExceptional;
                    break;
                case "GoodsTravelDaysUnit":
                    sortField = IssuingOrderOnWayTrackFields.GoodsTravelDaysUnit;
                    break;
                case "LastUpdatedDate":
                    sortField = IssuingOrderOnWayTrackFields.LastUpdatedDate;
                    break;
                case "LastUpdatedBy":
                    sortField = IssuingOrderOnWayTrackFields.LastUpdatedBy;
                    break;

            }
            SortExpression expression;
            if ((object)sortField != null)
            {
                SortOperator sortOperator = sortDirection == SortDirection.Ascending
                                                ? SortOperator.Ascending
                                                : SortOperator.Descending;
                expression = new SortExpression(sortField | sortOperator);
            }
            else
            {
                expression = new SortExpression(IssuingOrderOnWayTrackFields.PlannedGoodsDeliveredDate | SortOperator.Descending);
                expression.Add(IssuingOrderFields.TransportationPlanCode | SortOperator.Descending);
                expression.Add(IssuingOrderFields.ReceivingOrderDate | SortOperator.Descending);

            }


            var table = new DataTable();
            var dao = new TypedListDAO();
            dao.GetMultiAsDataTable(fields, table, 0, expression, GetIssuingOrderOnWayTrackSearchPredicate(criteria),
                                    GetIssuingOrderOnWayTrackSearchRelations(), false, null, null, pageIndex + 1, pageSize);


            return table;
        }
        public bool AddIssuingOrderOnWayTrack(IssuingOrderOnWayTrackData issuingOrderData)
        {
            var trans = new Transaction(IsolationLevel.ReadCommitted, "AddIssuingOrderOnWayTrack");
            try
            {
                // Save Order
                AddIssuingOrderOnWayTrack(issuingOrderData, trans);

                trans.Commit();
                return true;
            }
            catch (Exception)
            {
                trans.Rollback();
                throw;
            }
        }

        public bool ModifyIssuingOrderOnWayTrack(IssuingOrderOnWayTrackData issuingOrderData)
        {
            var trans = new Transaction(IsolationLevel.ReadCommitted, "ModifyIssuingOrderOnWayTrack");
            try
            {
                // Save Order
                ModifyIssuingOrderOnWayTrack(issuingOrderData, trans);
                trans.Commit();
                return true;
            }
            catch (Exception)
            {
                trans.Rollback();
                throw;
            }
        }

        public bool RemoveIssuingOrderOnWayTrack(Guid issuingOrderOnWayTrackId)
        {
            var trans = new Transaction(IsolationLevel.ReadCommitted, "RemoveIssuingOrderOnWayTrack");
            try
            {

                var orderItemsCollection = new IssuingOrderOnWayTrackCommentCollection();
                trans.Add(orderItemsCollection);
                orderItemsCollection.DeleteMulti(IssuingOrderOnWayTrackCommentFields.IssuingOrderOnWayTrackId == issuingOrderOnWayTrackId);

                var orderCollection = new IssuingOrderDeliveryCollection();
                trans.Add(orderCollection);
                orderCollection.DeleteMulti(IssuingOrderOnWayTrackFields.Id == issuingOrderOnWayTrackId);

                trans.Commit();
                return true;
            }
            catch (Exception)
            {
                trans.Rollback();
                throw;
            }
        }


        public IssuingOrderOnWayTrackData GetIssuingOrderOnWayTrack(Guid issuingOrderOnWayTrackId)
        {
            return GetIssuingOrderOnWayTrackData(new IssuingOrderOnWayTrackEntity(issuingOrderOnWayTrackId));
        }

        public IssuingOrderOnWayTrackData GetIssuingOrderOnWayTrackByIssuingOrderId(Guid issuingOrderId)
        {
            var metaData = new LinqMetaData();
            var onwayTrackData =
                 metaData.IssuingOrderOnWayTrack.FirstOrDefault(order => order.IssuingOrderId == issuingOrderId);
            if (onwayTrackData == null) return null;
            return GetIssuingOrderOnWayTrackData(onwayTrackData);
        }

        public bool RemoveIssuingOrderOnWayTrackComment(Guid issuingOrderOnWayTrackCommentId)
        {
            var trans = new Transaction(IsolationLevel.ReadCommitted, "RemoveissuingOrderOnWayTrackComment");
            try
            {

                var issuingOrderOnWayTrackCommentEntity = new IssuingOrderOnWayTrackCommentEntity(issuingOrderOnWayTrackCommentId);
                trans.Add(issuingOrderOnWayTrackCommentEntity);
                issuingOrderOnWayTrackCommentEntity.Delete();

                trans.Commit();
                return true;
            }
            catch (Exception)
            {
                trans.Rollback();
                throw;
            }
        }

        public IssuingOrderOnWayTrackCommentData GetIssuingOrderOnWayTrackComment(Guid issuingOrderOnWayTrackCommentId)
        {
            var issuingOrderDeliveryEntity = new IssuingOrderOnWayTrackCommentEntity(issuingOrderOnWayTrackCommentId);
            return GetIssuingOrderOnWayTrackCommentData(issuingOrderDeliveryEntity);
        }

        public IEnumerable<IssuingOrderOnWayTrackCommentData> GetIssuingOrderOnWayTrackCommentById(Guid issuingOrderOnWayTrackId)
        {
            var issuingOrderDeliveries = new IssuingOrderOnWayTrackCommentCollection();
            issuingOrderDeliveries.GetMulti(IssuingOrderOnWayTrackCommentFields.IssuingOrderOnWayTrackId == issuingOrderOnWayTrackId);
            return from issuingOrderDelivery in issuingOrderDeliveries select GetIssuingOrderOnWayTrackCommentData(issuingOrderDelivery);
        }
        #endregion
        #region Private provider
        private IssuingOrderOnWayTrackCommentEntity GetIssuingOrderOnWayTrackCommentEntity(IssuingOrderOnWayTrackCommentData issuingOrderOnWayTrackCommentData, IssuingOrderOnWayTrackCommentEntity issuingOrderOnWayTrackCommentEntity)
        {

            issuingOrderOnWayTrackCommentEntity.SolutionsForExceptions = issuingOrderOnWayTrackCommentData.Remark;
            issuingOrderOnWayTrackCommentEntity.GoodsDelayedReasons = issuingOrderOnWayTrackCommentData.GoodsDelayedReasons;
            issuingOrderOnWayTrackCommentEntity.Exceptions = issuingOrderOnWayTrackCommentData.Exceptions;

            return issuingOrderOnWayTrackCommentEntity;
        }
        private IssuingOrderOnWayTrackCommentData GetIssuingOrderOnWayTrackCommentData(IssuingOrderOnWayTrackCommentEntity issuingOrderOnWayTrackCommentEntity)
        {
            return new IssuingOrderOnWayTrackCommentData()
                       {
                           Id = issuingOrderOnWayTrackCommentEntity.Id,
                           Exceptions = issuingOrderOnWayTrackCommentEntity.Exceptions,
                           Remark = issuingOrderOnWayTrackCommentEntity.SolutionsForExceptions,
                           GoodsDelayedReasons = issuingOrderOnWayTrackCommentEntity.GoodsDelayedReasons,
                           IssuingOrderOnWayTrackId = issuingOrderOnWayTrackCommentEntity.IssuingOrderOnWayTrackId

                       };
        }
        private IssuingOrderOnWayTrackData GetIssuingOrderOnWayTrackData(IssuingOrderOnWayTrackEntity issuingOrderEntity)
        {
            var issuingOrderData = new IssuingOrderOnWayTrackData()
                       {
                           Id = issuingOrderEntity.Id,
                           GoodsTravelDays = issuingOrderEntity.GoodsTravelDays,
                           PlannedGoodsDeliveredDate = issuingOrderEntity.PlannedGoodsDeliveredDate,
                           GoodsCurrentPlace = issuingOrderEntity.GoodsCurrentPlace,
                           ActualDeliveredDate = issuingOrderEntity.ActualDeliveredDate,
                           GoodsDelayedDays = issuingOrderEntity.GoodsDelayedDays,
                           IsGoodsDelayed = issuingOrderEntity.IsGoodsDelayed,
                           IsGoodsExceptional = issuingOrderEntity.IsGoodsExceptional,
                           CreateBy = issuingOrderEntity.CreateBy,
                           CreatedDate = issuingOrderEntity.CreatedDate,
                           LastUpdatedBy = issuingOrderEntity.LastUpdatedBy,
                           LastUpdatedDate = issuingOrderEntity.LastUpdatedDate,
                           IssuingOrderId = issuingOrderEntity.IssuingOrderId,
                           GoodsTravelDaysUnit = issuingOrderEntity.GoodsTravelDaysUnit,
                           LastGoodsCurrentPlaceUpdatedDate = issuingOrderEntity.LastGoodsCurrentPlaceUpdatedDate,
                           LastGoodsCurrentPlaceUpdatedBy = issuingOrderEntity.LastGoodsCurrentPlaceUpdatedBy


                       };

            return issuingOrderData;
        }
        private IssuingOrderOnWayTrackEntity GetIssuingOrderOnWayTrackEntity(IssuingOrderOnWayTrackEntity issuingOrderEntity, IssuingOrderOnWayTrackData issuingOrder)
        {
            issuingOrderEntity.IssuingOrderId = issuingOrder.IssuingOrderId;
            issuingOrderEntity.GoodsTravelDays = issuingOrder.GoodsTravelDays;
            issuingOrderEntity.PlannedGoodsDeliveredDate = issuingOrder.PlannedGoodsDeliveredDate;
            issuingOrderEntity.GoodsCurrentPlace = issuingOrder.GoodsCurrentPlace;
            issuingOrderEntity.ActualDeliveredDate = issuingOrder.ActualDeliveredDate;
            issuingOrderEntity.GoodsDelayedDays = issuingOrder.GoodsDelayedDays;
            issuingOrderEntity.IsGoodsDelayed = issuingOrder.IsGoodsDelayed;
            issuingOrderEntity.IsGoodsExceptional = issuingOrder.IsGoodsExceptional;
            issuingOrderEntity.CreateBy = issuingOrder.CreateBy;
            issuingOrderEntity.CreatedDate = issuingOrder.CreatedDate;
            issuingOrderEntity.LastUpdatedBy = issuingOrder.LastUpdatedBy;
            issuingOrderEntity.LastUpdatedDate = issuingOrder.LastUpdatedDate;
            issuingOrderEntity.GoodsTravelDaysUnit = issuingOrder.GoodsTravelDaysUnit;
            issuingOrderEntity.LastGoodsCurrentPlaceUpdatedDate = issuingOrder.LastGoodsCurrentPlaceUpdatedDate;
            issuingOrderEntity.LastGoodsCurrentPlaceUpdatedBy = issuingOrder.LastGoodsCurrentPlaceUpdatedBy;


            return issuingOrderEntity;
        }
        private IPredicate GetIssuingOrderOnWayTrackSearchPredicate(IssuingOrderOnWayTrackSearchCriteria criteria)
        {
            var expression = new PredicateExpression();

            if (criteria.Id.HasValue && criteria.Id.Value != Guid.Empty)
            {
                expression.Add(IssuingOrderFields.Id == criteria.Id);
            }
            if (criteria.AreaId.HasValue && criteria.AreaId.Value != Guid.Empty)
            {
                expression.Add(IssuingOrderOnWayTrackFields.AreaId == criteria.AreaId);
            }
            if (criteria.OrderStatus.HasValue)
            {
                expression.Add(IssuingOrderFields.OrderStatus == criteria.OrderStatus);
            }
            if (criteria.BusinessType.HasValue)
            {
                expression.Add(IssuingOrderFields.BusinessType == criteria.BusinessType);
            }

            if (!string.IsNullOrEmpty(criteria.OrderCode))
            {
                expression.Add(IssuingOrderFields.OrderCode % ("%" + criteria.OrderCode + "%"));
            }
            if (criteria.CustomerId.HasValue && criteria.CustomerId.Value != Guid.Empty)
            {
                expression.Add(IssuingOrderFields.CustomerId == criteria.CustomerId);
            }

            if (!string.IsNullOrEmpty(criteria.CustomerName))
            {
                expression.Add(CustomerInfoFields.CustomerName % ("%" + criteria.CustomerName + "%"));
            }

            if (!string.IsNullOrEmpty(criteria.CustomerCode))
            {
                expression.Add(CustomerInfoFields.CustomerCode % ("%" + criteria.CustomerCode + "%"));
            }
            if (criteria.RouteTypeId.HasValue && criteria.RouteTypeId.Value != Guid.Empty)
            {
                expression.Add(IssuingOrderFields.RouteTypeId == criteria.RouteTypeId);
            }
            if (criteria.CheckoutType.HasValue)
            {
                expression.Add(IssuingOrderFields.CheckoutType == criteria.CheckoutType);
            }
            if (!string.IsNullOrEmpty(criteria.TransportationPlanCode))
            {
                expression.Add(IssuingOrderFields.TransportationPlanCode % ("%" + criteria.TransportationPlanCode + "%"));
            }
            if (criteria.IsGoodsDelayed.HasValue)
            {
                expression.Add(IssuingOrderOnWayTrackFields.IsGoodsDelayed == criteria.IsGoodsDelayed);
            }
            if (criteria.IsGoodsExceptional.HasValue)
            {
                expression.Add(IssuingOrderOnWayTrackFields.IsGoodsExceptional == criteria.IsGoodsExceptional);
            }


            if (criteria.ReceivingOrderDate != null)
            {
                if (criteria.ReceivingOrderDate.Start.HasValue)
                {
                    expression.Add(IssuingOrderFields.ReceivingOrderDate >= criteria.ReceivingOrderDate.Start);
                }
                if (criteria.ReceivingOrderDate.End.HasValue)
                {
                    expression.Add(IssuingOrderFields.ReceivingOrderDate <= criteria.ReceivingOrderDate.End);
                }
            }


            if (criteria.PlannedGoodsDeliveredDate != null)
            {
                if (criteria.PlannedGoodsDeliveredDate.Start.HasValue)
                {
                    expression.Add(IssuingOrderOnWayTrackFields.PlannedGoodsDeliveredDate >= criteria.PlannedGoodsDeliveredDate.Start);
                }
                if (criteria.PlannedGoodsDeliveredDate.End.HasValue)
                {
                    expression.Add(IssuingOrderOnWayTrackFields.PlannedGoodsDeliveredDate < criteria.PlannedGoodsDeliveredDate.End.Value.AddDays(1));
                }
            }

            if (criteria.ActualDeliveredDate != null)
            {
                if (criteria.ActualDeliveredDate.Start.HasValue)
                {
                    expression.Add(IssuingOrderOnWayTrackFields.ActualDeliveredDate >= criteria.ActualDeliveredDate.Start);
                }
                if (criteria.ActualDeliveredDate.End.HasValue)
                {
                    expression.Add(IssuingOrderOnWayTrackFields.ActualDeliveredDate < criteria.ActualDeliveredDate.End.Value.AddDays(1));
                }
            }
            if (!string.IsNullOrWhiteSpace(criteria.DeliveryProvince))
            {
                expression.Add(IssuingOrderFields.DeliveryProvince == criteria.DeliveryProvince);
            }
            if (!string.IsNullOrWhiteSpace(criteria.DeliveryCity))
            {
                expression.Add(IssuingOrderDeliveryFields.DeliveryCity == criteria.DeliveryCity);

            }
            if (!string.IsNullOrWhiteSpace(criteria.DeliveryOrderCode))
            {
                expression.Add(IssuingOrderDeliveryFields.DeliveryOrderCode % ("%" + criteria.DeliveryOrderCode + "%"));

            }
            return expression;
        }
        private IRelationCollection GetIssuingOrderOnWayTrackSearchRelations()
        {
            var relation = new RelationCollection(IssuingOrderOnWayTrackEntity.Relations.IssuingOrderEntityUsingIssuingOrderId, JoinHint.Left);
            relation.Add(IssuingOrderEntity.Relations.IssuingOrderDeliveryEntityUsingIssuingOrderId, JoinHint.Left);
            relation.Add(IssuingOrderEntity.Relations.CustomerInfoEntityUsingCustomerId, JoinHint.Left);
            relation.Add(new DynamicRelation(EntityType.IssuingOrderOnWayTrackEntity, JoinHint.Left, EntityType.UserEntity, string.Empty, string.Empty,
                                                    IssuingOrderOnWayTrackFields.LastUpdatedBy == UserFields.UserId));
            return relation;
        }
        private void AddIssuingOrderOnWayTrack(IssuingOrderOnWayTrackData issuingOrderOnWayTrackData, Transaction trans)
        {
            var issuingOrderEntity = new IssuingOrderOnWayTrackEntity();
            GetIssuingOrderOnWayTrackEntity(issuingOrderEntity, issuingOrderOnWayTrackData);
            issuingOrderEntity.Id = issuingOrderOnWayTrackData.Id;
            trans.Add(issuingOrderEntity);
            issuingOrderEntity.Save();

            AddIssuingOrderOnWayTrackComment(issuingOrderOnWayTrackData, trans, issuingOrderEntity);
            AddReceiptTrackInfoTrack(issuingOrderOnWayTrackData, trans);
        }
        private void AddIssuingOrderOnWayTrackComment(IssuingOrderOnWayTrackData issuingOrderOnWayTrackData, Transaction trans, IssuingOrderOnWayTrackEntity issuingOrderOnWayTrackEntity)
        {
            if (issuingOrderOnWayTrackData.IssuingOrderOnWayTrackCommentList == null) return;
            foreach (var issuingOrderOnWayTrackComment in issuingOrderOnWayTrackData.IssuingOrderOnWayTrackCommentList)
            {

                IssuingOrderOnWayTrackCommentEntity issuingOrderOnWayTrackCommentEntity =
                    new IssuingOrderOnWayTrackCommentEntity(issuingOrderOnWayTrackComment.Id);
                bool isNotDataValid = string.IsNullOrWhiteSpace(issuingOrderOnWayTrackComment.Exceptions) &&
                                   string.IsNullOrWhiteSpace(issuingOrderOnWayTrackComment.Remark) &&
                                   string.IsNullOrWhiteSpace(issuingOrderOnWayTrackComment.GoodsDelayedReasons);
                if (issuingOrderOnWayTrackCommentEntity.IsNew)
                {
                    if (isNotDataValid)
                    {
                        continue;
                    }
                    issuingOrderOnWayTrackCommentEntity.Id = Guid.NewGuid();
                }
                else
                {
                    if (isNotDataValid)
                    {
                        issuingOrderOnWayTrackCommentEntity.Delete();
                        trans.Add(issuingOrderOnWayTrackCommentEntity);
                        issuingOrderOnWayTrackCommentEntity.Save();
                        continue;
                    }
                }
                GetIssuingOrderOnWayTrackCommentEntity(issuingOrderOnWayTrackComment, issuingOrderOnWayTrackCommentEntity);

                issuingOrderOnWayTrackCommentEntity.IssuingOrderOnWayTrackId = issuingOrderOnWayTrackEntity.Id;
                trans.Add(issuingOrderOnWayTrackCommentEntity);
                issuingOrderOnWayTrackCommentEntity.Save();
            }
        }
        private void ModifyIssuingOrderOnWayTrack(IssuingOrderOnWayTrackData issuingOrderOnWayTrackData, Transaction trans)
        {
            var issuingOrderOnWayTrackEntity = new IssuingOrderOnWayTrackEntity(issuingOrderOnWayTrackData.Id);
            GetIssuingOrderOnWayTrackEntity(issuingOrderOnWayTrackEntity, issuingOrderOnWayTrackData);
            trans.Add(issuingOrderOnWayTrackEntity);
            issuingOrderOnWayTrackEntity.Save();

            if (issuingOrderOnWayTrackData.ActualDeliveredDate.HasValue && issuingOrderOnWayTrackData.ActualDeliveredDate.Value > DateTime.MinValue)
            {
                var issuingOrderEntity = new IssuingOrderEntity(issuingOrderOnWayTrackData.IssuingOrderId);

                issuingOrderEntity.OrderStatus = issuingOrderEntity.OrderStatus > (int)OrderStatus.OnWayTrackCompleted ? issuingOrderEntity.OrderStatus : (int)OrderStatus.OnWayTrackCompleted;

                trans.Add(issuingOrderEntity);
                issuingOrderEntity.Save();



                AddFlaggedPaymentMachineAccount(issuingOrderEntity, trans);
                AddRevenueMachineAccount(issuingOrderEntity, trans);
            }

            //insert onwaytrack history
            AddIssuingOrderOnWayTrackHistory(issuingOrderOnWayTrackData, trans, issuingOrderOnWayTrackEntity);
            AddIssuingOrderOnWayTrackComment(issuingOrderOnWayTrackData, trans, issuingOrderOnWayTrackEntity);
            AddReceiptTrackInfoTrack(issuingOrderOnWayTrackData, trans);
        }

        private void AddIssuingOrderOnWayTrackHistory(IssuingOrderOnWayTrackData issuingOrderOnWayTrackData, Transaction trans, IssuingOrderOnWayTrackEntity issuingOrderOnWayTrackEntity)
        {
            if (issuingOrderOnWayTrackData.NewIssuingOrderOnWayTrackHistory != null)
            {
                var entity = new IssuingOrderOnWayTrackHistoryEntity();
                entity.IssuingOrderOnWayTrackId = issuingOrderOnWayTrackData.Id;
                entity.GoodsCurrentPlace = issuingOrderOnWayTrackData.GoodsCurrentPlace;
                entity.LastUpdatedBy = issuingOrderOnWayTrackData.LastGoodsCurrentPlaceUpdatedBy;
                entity.LastUpdatedDate = issuingOrderOnWayTrackData.LastGoodsCurrentPlaceUpdatedDate;
                trans.Add(entity);
                entity.Save();
            }
        }

        private void AddRevenueMachineAccount(IssuingOrderEntity order, Transaction trans)
        {
            var revenueMachineAccountService = ServiceContainer.GetService<IRevenueMachineAccountService>();
            if (revenueMachineAccountService.ExistsRevenueMachineAccountByIssuingOrder(order.Id))
                return;

            var data = new RevenueMachineAccountData()
            {
                Id = Guid.NewGuid(),
                IssuingOrderId = order.Id,
                OrderCode = order.OrderCode,
                AreaId = order.AreaId,
                TransportationPlanCode = order.TransportationPlanCode,
                IsStatementofAccountCompleted = false,
                IsInvoiced = false,
                IsAccountsReceivable = false,
                DueInvoiceDate = order.ReceivingOrderDate.AddDays(45),
                AccountsReceivableDate = (order.ActualShippingDate ?? DateTime.Now).AddDays(90),
                CreatedDate = DateTime.Now,
                LastUpdatedDate = DateTime.Now,
                CreateBy = order.LastUpdatedBy,
                LastUpdatedBy = order.LastUpdatedBy,
                ////TotalGoodsUnloadingCost = order.IssuingOrderVehicleInfo.Sum(a => a.GoodsUnloadingPirce ?? 0),
                ////TotalCarSharingPrice = order.IssuingOrderVehicleInfo.Sum(a => a.CarSharingPrice ?? 0),
                ////ExtraCost = order.MachineAccountPayment.Sum(a => a.OtherAmountFromManufactor) - order.MachineAccountPayment.Sum(a => a.DeductionExceptionsAmount),
                RevenueUnitCost = 1

            };
            revenueMachineAccountService.AddRevenueMachineAccount(trans, data);



        }

        private void AddFlaggedPaymentMachineAccount(IssuingOrderEntity order, Transaction trans)
        {
            //check flagged paymentMachine and AddPaymentMachine

            var paymentAccountService = ServiceContainer.GetService<IMachineAccountService>();
            if (paymentAccountService.ExistsPaymentMachineAccountByIssuingOrder(order.Id))
                return;
            var data = new MachineAccountData()
                           {
                               Id = Guid.NewGuid(),
                               IssuingOrderId = order.Id,
                               AreaId = order.AreaId,
                               OrderCode = order.OrderCode,
                               PaymentOrIncomeDate = DateTime.Now,
                               IsFlag = true,
                               TransportationPlanCode = order.TransportationPlanCode,
                               TobePaidShippingCost = 0,
                               DeductionExceptionsAmount = 0,
                               OtherAmountFromManufactor = 0,
                               PaymentOrIncome = MachineAccountType.Payment,

                               CreatedDate = DateTime.Now,
                               LastUpdatedDate = DateTime.Now,
                               CreateBy = order.LastUpdatedBy,
                               LastUpdatedBy = order.LastUpdatedBy,

                           };

            var paymentMethodData =
                ServiceContainer.GetService<IDictionaryService>().GetDataItems("付款方式", order.AreaId).FirstOrDefault();
            if (paymentMethodData == null)
            {
                data.PaymentMethod = paymentMethodData.Value;
            }
            else
            {
                data.PaymentMethod = Guid.NewGuid();
            }

            paymentAccountService.AddMachineAccounts(data, trans);
        }


        private void AddReceiptTrackInfoTrack(IssuingOrderOnWayTrackData issuingOrderOnWayTrackData, Transaction trans)
        {
            if (issuingOrderOnWayTrackData.ActualDeliveredDate.HasValue && issuingOrderOnWayTrackData.ActualDeliveredDate.Value > DateTime.MinValue)
            {
                //check
                var hasReceipt =
             ServiceContainer.GetService<IIssuingOrderReceiptInfoTrackService>().CheckIssuingOrderReceiptInfoExists(issuingOrderOnWayTrackData.IssuingOrderId);
                if (hasReceipt) return;

                var service = ServiceContainer.GetService<IIssuingOrderService>();
                var issuingOrderDeliveries = service.GetIssuingOrderDeliveryByOrderId(issuingOrderOnWayTrackData.IssuingOrderId);
                foreach (var issuingOrderDelivery in issuingOrderDeliveries)
                {
                    var issuingOrderReceiptInfoTrackEntity = new IssuingOrderReceiptInfoTrackEntity()
                    {
                        Id = Guid.NewGuid(),
                        IssuingOrderDeliveryId = issuingOrderDelivery.Id,
                        IssuingOrderId = issuingOrderDelivery.IssuingOrderId,
                        ReceiptInfoCopies = 1,
                        ReceiptInfoDelayedDays = 0,
                        CreatedDate = DateTime.Now,
                        LastUpdatedDate = DateTime.Now,
                        CreateBy = issuingOrderOnWayTrackData.LastUpdatedBy,
                        LastUpdatedBy = issuingOrderOnWayTrackData.LastUpdatedBy,
                        IsReceiptInfoDelayed = false,
                        IsReceiptInfoExceptional = false,
                        AreaId = issuingOrderDelivery.AreaId,
                        ReceiptOnWayDaysUnit = (int)GoodsTravelDayUnit.Day

                    };
                    trans.Add(issuingOrderReceiptInfoTrackEntity);
                    issuingOrderReceiptInfoTrackEntity.Save();
                }

            }

        }
        #endregion
    }
}
